package com.hezuti.novel.parser.qidian;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

import javax.swing.text.html.parser.TagElement;

import org.htmlparser.Node;
import org.htmlparser.NodeFilter;
import org.htmlparser.Tag;
import org.htmlparser.filters.AndFilter;
import org.htmlparser.filters.HasAttributeFilter;
import org.htmlparser.filters.TagNameFilter;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.visitors.NodeVisitor;

import com.hezuti.novel.domain.Author;
import com.hezuti.novel.domain.Book;
import com.hezuti.novel.domain.Category;
import com.hezuti.novel.domain.Volume;
import com.hezuti.util.DBManager;
import com.hezuti.util.RegexUtil;
import com.hezuti.util.SimpleDateFormatUtil;
import com.sun.net.httpserver.Filter;

public class QidianBookInfoVisitor extends NodeVisitor {
	
	private DBManager db;
	
	private static String[] SIGN={"VIP卷","正文","作品相关"};
	
	
	@Override
	public void beginParsing() {
		db=new DBManager();
		db.getConnection();
		super.beginParsing();
	}
	@Override
	public void finishedParsing() {
		
		try {
			db.execute("commit;");
			if(db!=null){
				db.close_DB_Object();
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		super.finishedParsing();
	}
	@Override
	public boolean shouldRecurseChildren() {
	return true;
	}
	private Book book;
	
	public QidianBookInfoVisitor(Book book) {
		this.book=book;
	}
	@Override
	public void visitTag(Tag tag) {
		if(tag.getClass().equals(Div.class)){
			NodeList children = tag.getChildren();
		if("page_site".equals(tag.getAttribute("class"))){//
			String c1=children.elementAt(3).toPlainTextString().replaceAll("&(.*?);|\\s", "");
			c1=RegexUtil.clearStr(c1);
			int c1Id=checkDbCategory(c1,null);
			String c2=children.elementAt(5).toPlainTextString();
			c2=RegexUtil.clearStr(c2);
			int c2Id=checkDbCategory(c2, c1Id==-1?0:c1Id);
			book.setCategoryId(c2Id);
			//获取书号
			book.setBookId(children.elementAt(10).toPlainTextString().replace(")","").replace("(书号","").trim());
			
		}else if("booktitle".equals(tag.getAttribute("class"))){
			book.setBookName(RegexUtil.clearStr(children.elementAt(1).toPlainTextString()));
			String authorName=children.elementAt(3).getChildren().elementAt(1).toPlainTextString();
			authorName=RegexUtil.clearStr(authorName);
			int aid=checkDbAuthor(authorName,book.getFrom());
			book.setAuthorId(aid);
			//一本书的信息完了入库；
			int myId=checkDbBook();
			book.setId(myId);
		}else if("content".equals(tag.getAttribute("id"))){//
			NodeList nodes = tag.getChildren();
			for(int i=0;i<nodes.size();i++){
				Node volNode = nodes.elementAt(i).getFirstChild();
				Node chapterNode = nodes.elementAt(i+1);
				Node vol=null;
				if(volNode!=null&&(vol=volNode.getChildren().elementAt(1))!=null){
					String volumeName=RegexUtil.clearStr(vol.getText());
					String volumeInfo="";
					if(chapterNode.getChildren().size()==2){
						volumeInfo=chapterNode.getFirstChild().toPlainTextString();
					}
					//将书卷入库,返回id
					final int vid=checkDbVolume(volumeName, volumeInfo);
					
					NodeList chapters = chapterNode.getLastChild().getFirstChild().getChildren();
					for(int j=0;j<chapters.size();j++){
						Node chapter = chapters.elementAt(j);
						chapter.accept(new NodeVisitor() {
							@Override
							public void visitTag(Tag tag) {
								if(tag.getClass().equals(LinkTag.class)){
									String title = tag.getAttribute("title");
									title=title.substring(title.lastIndexOf("：")+1);
									long time=SimpleDateFormatUtil.parserStr2Long(title);
									String uri=tag.getAttribute("href");
									if(!uri.startsWith("http://")){
										uri="http://"+book.getFrom()+uri;
									}
									String sid=uri.substring(uri.lastIndexOf(",")+1,uri.lastIndexOf("."));
									String chapterName=tag.toPlainTextString();
									checkDbChapter(chapterName, uri, vid, time, sid);
								}
							}
						});
					}
				}
			}
		}
		}
		
	}

	
	
	/**
	 * 检测 书是否存在<br/>
	 * 最后返回类别id
	 * @param name
	 * @return
	 */
	public int checkDbBook(){
		int id=-1;
		try {
			while(id==-1){
				ResultSet rs = db.executeSql1("select id from book where source_id = '"+book.getBookId()+"' "+"and author_id="+book.getAuthorId());
				if(rs.next()){
					id=rs.getInt(1);
				}else{
					db.execute("insert into  book(name,author_id,from_site,source_uri,source_id,category_id) values('"+book.getBookName()+"',"+book.getAuthorId()+",'"+book.getFrom()+"','"+book.getUri()+"','"+book.getBookId()+"',"+book.getCategoryId()+")");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}
	/**
	 * 检测 分类是否存在<br/>
	 * 最后返回类别id
	 * @param category
	 * @return
	 */
	public int checkDbCategory(String category,Integer fatherId){
		int id=-1;
		try {
			while(id==-1){
			ResultSet rs = db.executeSql1("select id from category where name = '"+category+"'");
			if(rs.next()){
				id=rs.getInt(1);
			}else{
				System.out.println("category  "+category +" not in db ,now insert into ...");
				if(null==fatherId){
					db.execute("insert into category(name) values('"+category+"');");
				}else{
					db.execute("insert into category(name,father_id) values('"+category.trim()+"',"+fatherId+");");
				}
			}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return id;
	}
	
	/**
	 * 检测 分类是否存在<br/>
	 * 最后返回类别id
	 * @param category
	 * @return
	 */
	public int checkDbAuthor(String authoName,String fromSite){
		int id=-1;
		try {
			while(id==-1){
			ResultSet rs = db.executeSql1("select id from user where name = '"+authoName+"' and from_site='"+fromSite+"'");
			if(rs.next()){
				System.out.println("user :  "+authoName +" has in db.user;");
				id=rs.getInt(1);
			}else{
				System.out.println("user :  "+authoName +" not in db.user ;");
				db.execute("insert into user(name,from_site) values('"+authoName+"','"+fromSite+"');");
			}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}
	
	/**
	 * 检测 书卷是否存在<br/>
	 * 最后返回类别id
	 * @param volume
	 * @return
	 */
	public int checkDbVolume(String volumeName,String info){
		int id=-1;
		try {
			while(id==-1){
			ResultSet rs = db.executeSql1("select id from volume where name = '"+volumeName+"' and book_id="+book.getId());
			if(rs.next()){
				System.out.println("vlume :  "+volumeName +" has in db ;");
				id=rs.getInt(1);
			}else{
				System.out.println("volume :  "+volumeName +" not in db ;");
				db.execute("insert into volume(name,info,book_id) values('"+volumeName+"','"+info+"',"+book.getId()+");");
			}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}
	
	/**
	 * 检测 书卷是否存在<br/>
	 * 最后返回类别id
	 * @param volume
	 * @return
	 */
	public int checkDbChapter(String chapterName,String sourceUri,int volumeId,long time,String sid){
		int id=-1;
		try {
			while(id==-1){
			ResultSet rs = db.executeSql1("select id from chapter where source_id = '"+sid+"' and volume_id="+volumeId);
			if(rs.next()){
				System.out.println("chapter :  "+chapterName +" has in db ;");
				id=rs.getInt(1);
			}else{
				System.out.println("chapter :  "+chapterName +" not in db ;");
				db.execute("insert into chapter(name,source_uri,source_id,update_time,volume_id) values('"+chapterName+"','"+sourceUri+"','"+sid+"',"+time+","+volumeId+");");
			}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return id;
	}
}
